package com.linkoog.devtools.intellij.ui.table.column_info.column;

import com.linkoog.devtools.intellij.ui.table.TableRowData;
import com.linkoog.devtools.intellij.ui.table.column_info.provider.TableCellEditorProvider;
import com.linkoog.devtools.intellij.ui.table.column_info.provider.TableCellRendererProvider;
import com.linkoog.devtools.intellij.ui.table.column_info.provider.TableCellValueGetterProvider;
import com.linkoog.devtools.intellij.ui.table.column_info.provider.TableCellValueSetterProvider;
import com.linkoog.devtools.intellij.ui.table.column_info.provider.TableCellWidthProvider;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;

@Getter
public class TableColumnInfo<T extends TableRowData> extends AbstractColumnInfo<T, Object> {

    private final String columnName;
    private final String fieldName;
    private final TableCellWidthProvider tableCellWidthProvider;
    private final TableCellValueGetterProvider<T> tableCellValueGetterProvider;
    private final TableCellValueSetterProvider<T> tableCellValueSetterProvider;
    private final TableCellEditorProvider<T> editorProvider;
    private final TableCellRendererProvider<T> rendererProvider;



    public TableColumnInfo(@NotNull String columnName,
                            @NotNull String fieldName,
                           TableCellWidthProvider tableCellWidthProvider,
                           @NotNull TableCellValueGetterProvider<T> tableCellValueGetterProvider,
                           @NotNull TableCellValueSetterProvider<T> tableCellValueSetterProvider,
                           TableCellRendererProvider<T> rendererProvider,
                           TableCellEditorProvider<T> editorProvider) {
        super(columnName);
        this.columnName = columnName;
        this.fieldName = fieldName;
        this.tableCellWidthProvider = tableCellWidthProvider;
        this.tableCellValueGetterProvider = tableCellValueGetterProvider;
        this.tableCellValueSetterProvider = tableCellValueSetterProvider;
        this.rendererProvider = rendererProvider;
        this.editorProvider = editorProvider;
    }

    @Override
    public int getWidth(JTable table) {
        if (tableCellWidthProvider == null) return -1;
        return tableCellWidthProvider.getWidth(table);
    }

    @Nullable
    @Override
    public Object valueOf(T itemInfo) {
        return tableCellValueGetterProvider.valueOf(itemInfo);
    }

    @Override
    public boolean isCellEditable(T itemInfo) {
        return itemInfo.getEditable(fieldName);
    }

    @Override
    public void setValue(T itemInfo, Object value) {
        tableCellValueSetterProvider.setValue(itemInfo, value);
    }

    @Nullable
    @Override
    public TableCellEditor getEditor(T itemInfo) {
        if (editorProvider == null) return null;
        return editorProvider.getEditor(itemInfo);
    }

    @Nullable
    @Override
    public TableCellRenderer getRenderer(T itemInfo) {
        if (rendererProvider == null) return null;
        return rendererProvider.getRenderer(itemInfo);
    }

    public static <T extends TableRowData> TableColumnInfoBuilder<T> builder(){
        return new TableColumnInfoBuilder<>();
    }


    public static class TableColumnInfoBuilder<T extends TableRowData> {
        private String columnName;
        private String fieldName;
        private TableCellWidthProvider tableCellWidthProvider;
        private TableCellValueGetterProvider<T> tableCellValueGetterProvider;
        private TableCellValueSetterProvider<T> tableCellValueSetterProvider;
        private TableCellEditorProvider<T> editorProvider;
        private TableCellRendererProvider<T> rendererProvider;

        public TableColumnInfoBuilder<T> columnName(String columnName) {
            this.columnName = columnName;
            return this;
        }

        public TableColumnInfoBuilder<T> fieldName(String fieldName) {
            this.fieldName = fieldName;
            return this;
        }

        public TableColumnInfoBuilder<T> tableCellWidthProvider(TableCellWidthProvider tableCellWidthProvider) {
            this.tableCellWidthProvider = tableCellWidthProvider;
            return this;
        }

        public TableColumnInfoBuilder<T> tableCellValueGetterProvider(TableCellValueGetterProvider<T> tableCellValueGetterProvider) {
            this.tableCellValueGetterProvider = tableCellValueGetterProvider;
            return this;
        }

        public TableColumnInfoBuilder<T> tableCellValueSetterProvider(TableCellValueSetterProvider<T> tableCellValueSetterProvider) {
            this.tableCellValueSetterProvider = tableCellValueSetterProvider;
            return this;
        }

        public TableColumnInfoBuilder<T> editorProvider(TableCellEditorProvider<T> editorProvider) {
            this.editorProvider = editorProvider;
            return this;
        }

        public TableColumnInfoBuilder<T> rendererProvider(TableCellRendererProvider<T> rendererProvider) {
            this.rendererProvider = rendererProvider;
            return this;
        }

        public TableColumnInfo<T> build() {
            return new TableColumnInfo<T>(columnName, fieldName, tableCellWidthProvider, tableCellValueGetterProvider, tableCellValueSetterProvider, rendererProvider, editorProvider);
        }
    }


}
